from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from django.http import HttpResponseNotAllowed, JsonResponse
from django.shortcuts import render, redirect
from django.urls import reverse_lazy
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_protect
from django.views.generic import ListView, DetailView, DeleteView
from django.db.models import Prefetch
from feedbacks.models import Feedback
from user.forms import CommentForm
from .models import *
from django.shortcuts import render, get_object_or_404
from django.db.models import Q

# Create your views here.

class FilesListView(ListView):
    model = Files


@method_decorator(csrf_protect, name='dispatch')
class FilesDetailView(DetailView):
    queryset = Files.objects.all()
    model = Files
    template_name = 'main/files_detail.html'
    context_object_name = 'object'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        file = self.object

        # 权限检查逻辑
        has_commented = False
        if self.request.user.is_authenticated:
            has_commented = Comment.objects.filter(file=file, user=self.request.user).exists()

        can_see_download = (self.request.user == file.author) or has_commented

        # 评论相关数据
        comments = file.comments.all()
        form = CommentForm()

        context.update({
            'can_see_download': can_see_download,
            'has_commented': has_commented,
            'comments': comments,
            'comment_form': form,
            'comment_count': comments.count(),
        })

        return context

    def post(self, request, *args, **kwargs):
        self.object = self.get_object()
        file = self.object

        if 'comment' in request.POST:
            if not request.user.is_authenticated:
                return redirect('user:login')

            form = CommentForm(request.POST)
            if form.is_valid():
                comment = form.save(commit=False)
                comment.file = file
                comment.user = request.user
                comment.save()

                return redirect('main:files_detail', pk=file.id)


        context = self.get_context_data(**kwargs)
        return self.render_to_response(context)





class ClassDetailView(DetailView):
    queryset = Category.objects.all()


# def files_list(request):
#     # 只取顶级分类，并预抓取它们下面的所有文章
#     categorys = Category.objects.filter(parent__isnull=True) \
#         .prefetch_related(
#         Prefetch('articles',
#                  queryset=Files.objects.all(),
#                  to_attr='articles')  # 模板里用 c.articles
#     )
#     return render(request, 'files_list.html', {'categorys': categorys})


def category_detail(request, pk):
    print('>>> 进入 category_detail，pk=', pk)
    category = get_object_or_404(Category, pk=pk)
    print('>>> 当前分类:', category, category.id)
    # 多对多过滤：属于该分类且已审核
    files = Files.objects.filter(
        categorys=category,
    ).order_by('-create_time')
    print('>>> 查到 files 数量：', files.count())
    return render(request, 'main/category_detail.html', {
        'object': category,
        'files': files,  # 关键变量
    })


def files_by_tag(request, tag_id):
    """根据标签显示文件"""
    tag = get_object_or_404(Tag, id=tag_id)
    files = Files.objects.filter(tags=tag).order_by('-create_time')

    if not request.user.is_authenticated:
        # 未登录用户：只显示已通过的文件
        files = files.filter(state='success')
    elif not request.user.is_superuser:
        # 普通登录用户：显示自己的所有文件 + 其他人的已通过文件
        files = files.filter(
            Q(author=request.user) |  # 自己的文件（所有状态）
            Q(state='success')  # 其他人的已通过文件
        )
        # 管理员：显示所有文件（不需要额外筛选）

        # 排序
    files = files.order_by('-create_time')

    context = {
        'tag': tag,
        'files': files,
        'page_title': f'标签: {tag.title}'
    }
    return render(request, 'main/files_by_tag.html', context)


def file_detail(request, file_id):
    file = get_object_or_404(Files, id=file_id)

    # 检查用户是否已经评论过
    has_commented = False
    if request.user.is_authenticated:
        has_commented = Comment.objects.filter(file=file, user=request.user).exists()

    # 作者可以立即看到下载地址，其他用户需要评论后才能看到
    can_see_download = (request.user == file.author) or has_commented

    # 处理评论提交
    if request.method == 'POST' and 'comment' in request.POST:
        if not request.user.is_authenticated:
            return redirect('user:login')

        form = CommentForm(request.POST)
        if form.is_valid():
            comment = form.save(commit=False)
            comment.file = file
            comment.user = request.user
            comment.save()
            return redirect('main:file_detail', file_id=file.id)
    else:
        form = CommentForm()

    # 获取所有评论
    comments = file.comments.all()

    context = {
        'object': file,
        'can_see_download': can_see_download,  # 恢复权限检查
        'has_commented': has_commented,  # 恢复评论状态
        'comments': comments,
        'comment_form': form,
        'comment_count': comments.count(),
    }
    return render(request, 'main/files_detail.html', context)


def files_change_state(request, pk):
    files_obj = get_object_or_404(Files, pk=pk)
    if request.method == 'POST':
        print(request.POST.get('state'))
        new_state = request.POST.get('state')


        if new_state in {'success', 'fail', 'undo'}:
            files_obj.state = new_state
            files_obj.save(update_fields=['state'])
    return redirect('main:files_detail', pk=pk)


class CommentDeleteView(LoginRequiredMixin, UserPassesTestMixin, DeleteView):
    model = Comment
    success_url = reverse_lazy('main:index')

    def get(self, request, *args, **kwargs):
        return HttpResponseNotAllowed(['POST'])

    def test_func(self):
        comment = self.get_object()  # 当前要删除的评论
        user = self.request.user
        # print("123456",user, comment.user, comment.file.author,
        #       user == comment.user or user.is_staff or user == comment.file.author)
        return (
                user == comment.file.author or
                user.is_staff or
                user == comment.user
        )


    def get_success_url(self):
        return self.request.POST.get('back') or self.request.META.get('HTTP_REFERER') or reverse_lazy('main:index')










